﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using blackhouse.BlackApart.Business.Apartments;

namespace blackhouse.BlackApart.Business.Prices {
    public class ComputedApartmentPrice : IApartmentPrice {

        #region Fields

        private List<IApartmentPrice> prices = new List<IApartmentPrice>();
        private Factory factory = Factory.Instance();
        private HashSet<IPriceRabat> priceRabats = new HashSet<IPriceRabat>();

        #endregion

        #region Constructors

        public ComputedApartmentPrice(DateTime arrivalDate, DateTime departureDate) {
            this.ReservationFromDay = arrivalDate;
            this.ReservationToDay = departureDate;
        }

        #endregion

        #region IApartmentPrice Members

        public int ReservationNumberOfPeoples {
            get { return this.prices.Sum(p => p.ReservationNumberOfPeoples); }
            set { }
        }

        public DateTime ReservationFromDay {
            get;
            set;
        }

        public DateTime ReservationToDay {
            get;
            set;
        }

        public double GetPrice() {
            return this.prices.Sum(p => p.GetPrice());
        }

        public double GetPriceWithoutRabat() {
            return this.prices.Sum(p => p.GetPriceWithoutRabat());
        }

        public float GetRabatValue() {
            return this.prices.Average(p => p.GetRabatValue());
        }

        #endregion

        #region Methods

        public IApartmentPrice AddApartmentPrice(IApartment apartment, int numberOfPeoples) {
            IApartmentPrice price = factory.GetApartmentPrice(apartment.Id);
            price.ReservationNumberOfPeoples = numberOfPeoples;
            price.ReservationFromDay = this.ReservationFromDay;
            price.ReservationToDay = this.ReservationToDay;
            foreach (IPriceRabat rabat in this.priceRabats)
                price.ApplyPriceRabat(rabat);
            this.prices.Add(price);
            return price;
        }

        public IPriceRabat[] GetAssociacedRabats() {
            return this.priceRabats.ToArray();
        }

        public void ApplyPriceRabat(IPriceRabat rabat) {
            foreach (IApartmentPrice price in this.prices) {
                price.ApplyPriceRabat(rabat);
            }
            IPriceRabat prevRabat = this.priceRabats.FirstOrDefault(r => r.RabatKey == rabat.RabatKey);
            if (prevRabat != null)
                this.priceRabats.Remove(prevRabat);
            this.priceRabats.Add(rabat);
        }

        #endregion

    }
}
